package com.jbp.service.impl;

import com.jbp.dao.UserPacksackDao;
import com.jbp.exception.RRException;
import com.jbp.model.*;
import com.jbp.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jbp.utils.PageUtils;
import com.jbp.utils.Query;
import org.springframework.transaction.annotation.Transactional;


@Service
public class UserPacksackServiceImpl extends ServiceImpl<UserPacksackDao, UserPacksack> implements UserPacksackService {
    @Autowired
    private GiftService giftService;
    @Autowired
    private RoomService roomService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private WalletRecordService walletRecordService;
    @Autowired
    private SendGiftRecordService sendGiftRecordService;
    @Autowired
    private UserService userService;
    @Autowired
    private RoomWheatService roomWheatService;
    @Autowired
    private IncomeService incomeService;
    @Autowired
    private UserNobilityService userNobilityService;
    @Autowired
    private UserDailySendgiftRecordService userDailySendgiftRecordService;
    @Autowired
    private UserLevelService userLevelService;
    @Autowired
    private UserSendGiftLogService userSendGiftLogService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserPacksack> page = this.page(
                new Query<UserPacksack>().getPage(params),
                new QueryWrapper<UserPacksack>()
        );

        return new PageUtils(page);
    }

    //背包送礼
    @Override
    @Transactional
    public synchronized void sendPackGift(Map<String, Object> params) {
        //房间Id
        Integer roomId = (Integer) params.get("roomId");
        //我的id
        Integer userId = (Integer) params.get("userId");
        //礼物id
        Integer giftId = (Integer) params.get("giftId");
        //礼物数量
        Integer num = (Integer) params.get("num");
        if (num<=0) {
            throw new RRException("礼物数量错误");
        }
        //送给目标用户id，以，分隔
        String otherId = (String) params.get("otherId");
        ArrayList<Integer> otherIds = new ArrayList<>();
        for (String idStr : otherId.split(",")) {
            if (idStr!=null) {
                otherIds.add(Integer.parseInt(idStr));
            }
        }

        //检查目标用户
        if (otherIds.size()==0) {
            throw new RRException("目标用户错误");
        }

        //检查房间id
        Room room = roomService.getById(roomId);
        if (room == null) {
            throw new RRException("房间错误");
        }
        //检查礼物id
        Gift gift = giftService.getById(giftId);
        if (gift == null) {
            throw new RRException("礼物错误");
        }
        //检查礼物数量
        QueryWrapper<UserPacksack> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.eq("gift_id", giftId);
        UserPacksack packsack = getOne(queryWrapper);
        if (packsack==null || packsack.getNumber() < num * otherIds.size()) {
            throw new RRException("礼物数量不足");
        }

        //背包礼物扣除
        if (packsack.getNumber() - num * otherIds.size() == 0) {
            //如果礼物为0 删除这条数据
            removeById(packsack.getId());
        } else {
            packsack.setNumber(packsack.getNumber() - num * otherIds.size());
            updateById(packsack);
        }

        otherIds.forEach(otherUserId->{
            //别人钱包变动记录
            Wallet otherWallet = walletService.getByUserId(otherUserId);
            double changeBalance = gift.getCoin() * num * 0.7d;
            double afterAixin = otherWallet.getAixin().doubleValue() + changeBalance;

            WalletRecord walletRecordOther = new WalletRecord();
            walletRecordOther.setOperationType("recive_gift");
            walletRecordOther.setCoinType("aixin");
            walletRecordOther.setAddType("add");
            walletRecordOther.setBeforeBalance(otherWallet.getAixin());
            walletRecordOther.setChangeBalance(BigDecimal.valueOf(changeBalance));
            walletRecordOther.setAfterBalance(BigDecimal.valueOf(afterAixin));
            walletRecordOther.setUserId(otherUserId);
            walletRecordService.save(walletRecordOther);

            //别人爱心增加
            otherWallet.setAixin(BigDecimal.valueOf(afterAixin));
            walletService.updateWithLock(otherWallet);

            //送礼记录
            SendGiftRecord giftRecord = new SendGiftRecord();
            giftRecord.setGiftId(gift.getId());
            giftRecord.setGiftName(gift.getName());
            giftRecord.setGiftImg(gift.getImgUrl());
            giftRecord.setGiftPrice(gift.getCoin());
            giftRecord.setNum(num);
            giftRecord.setFromUserId(userId);
            giftRecord.setToUserId(otherUserId);
            giftRecord.setRoomId(roomId);
            giftRecord.setType("bag");
            sendGiftRecordService.save(giftRecord);

            //麦位心动值增加
            roomWheatService.addCharm(otherUserId, roomId, gift.getCoin() * num);

            userDailySendgiftRecordService.updateSendGiftRecord(userId, otherUserId, gift.getCoin() * num, roomId, "bag");

            //送礼消息
            String log = gift.getName()+"("+gift.getCoin()+")*"+num+ " 总计:"+gift.getCoin() * num;
            userSendGiftLogService.sendGiftMsg(userId, otherUserId, log);

            UserSendGiftLog userSendGiftLog = new UserSendGiftLog();
            userSendGiftLog.setFromUserId(userId);
            userSendGiftLog.setToUserId(otherUserId);
            userSendGiftLog.setContent(log);
            userSendGiftLog.setType("bag");
            userSendGiftLog.setRoomId(roomId);
            userSendGiftLog.setTotalPrice(gift.getCoin() * num);
            userSendGiftLog.setImg(gift.getImgUrl());
            userSendGiftLogService.save(userSendGiftLog);
        });


        int totalPrice = otherIds.size() * num * gift.getCoin();

        //发放流水提成
        incomeService.deployIncome(room.getId(), totalPrice, "bag");

        userNobilityService.addScore(userId, totalPrice);

        //自己经验值增加
        userLevelService.addScore(userId, totalPrice);
        //房间人气值增加
        room.setMood(room.getMood()+gift.getCoin() * num * otherIds.size());
        roomService.updateById(room);


    }

    @Override
    @Transactional
    public synchronized void sendAllPackGift(Map<String, Object> params) {
        //房间Id
        Integer roomId = (Integer) params.get("roomId");
        //我的id
        Integer userId = (Integer) params.get("userId");
        //送给目标用户id，以，分隔
        Integer otherId = (Integer) params.get("otherId");

        //检查房间id
        Room room = roomService.getById(roomId);
        if (room == null) {
            throw new RRException("房间错误");
        }
        //检查礼物数量
        QueryWrapper<UserPacksack> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        List<UserPacksack> packsackList = list(queryWrapper);
        if (packsackList==null || packsackList.size()==0) {
            throw new RRException("背包为空");
        }

        int totalPrice = 0;
        Gift biggestGift = null;
        List<SendGiftRecord> sendGiftRecords = new ArrayList<>();
        for (UserPacksack packsack : packsackList) {
            Gift gift = giftService.getById(packsack.getGiftId());
            if (biggestGift==null || biggestGift.getCoin()< gift.getCoin()) {
                biggestGift = gift;
            }

            int num = packsack.getNumber();

            totalPrice += gift.getCoin()*num;
            //背包礼物扣除
            removeById(packsack.getId());

            //别人钱包变动记录
            Wallet otherWallet = walletService.getByUserId(otherId);
            double changeBalance = gift.getCoin() * num * 0.7d;
            double afterAixin = otherWallet.getAixin().doubleValue() + changeBalance;

            WalletRecord walletRecordOther = new WalletRecord();
            walletRecordOther.setOperationType("recive_gift");
            walletRecordOther.setCoinType("aixin");
            walletRecordOther.setAddType("add");
            walletRecordOther.setBeforeBalance(otherWallet.getAixin());
            walletRecordOther.setChangeBalance(BigDecimal.valueOf(changeBalance));
            walletRecordOther.setAfterBalance(BigDecimal.valueOf(afterAixin));
            walletRecordOther.setUserId(otherId);
            walletRecordService.save(walletRecordOther);

            //别人爱心增加
            otherWallet.setAixin(BigDecimal.valueOf(afterAixin));
            walletService.updateWithLock(otherWallet);

            //送礼记录
            SendGiftRecord giftRecord = new SendGiftRecord();
            giftRecord.setGiftId(packsack.getGiftId());
            giftRecord.setGiftName(gift.getName());
            giftRecord.setGiftImg(gift.getImgUrl());
            giftRecord.setGiftPrice(gift.getCoin());
            giftRecord.setNum(num);
            giftRecord.setFromUserId(userId);
            giftRecord.setToUserId(otherId);
            giftRecord.setRoomId(roomId);
            giftRecord.setType("bag");
            sendGiftRecordService.save(giftRecord);
            sendGiftRecords.add(giftRecord);
        }

        //发放流水提成
        incomeService.deployIncome(room.getId(), totalPrice, "bag");

        int finalTotalPrice = totalPrice;
        //麦位心动值增加
        roomWheatService.addCharm(otherId, roomId, finalTotalPrice);

        userNobilityService.addScore(userId, totalPrice);

        //自己经验值增加
        userLevelService.addScore(userId, totalPrice);

        //房间人气值增加
        room.setMood(room.getMood()+ finalTotalPrice);
        roomService.updateById(room);

        userDailySendgiftRecordService.updateSendGiftRecord(userId, otherId, totalPrice, roomId, "bag");

        //送礼消息
        Collections.sort(sendGiftRecords, Comparator.comparingInt(SendGiftRecord::getGiftPrice).reversed());
        String log = "";
        for (SendGiftRecord record : sendGiftRecords) {
            log = log + record.getGiftName() +"("+record.getGiftPrice()+")*"+record.getNum()+" ";
        }
        log = log + "总计:"+totalPrice;
        userSendGiftLogService.sendGiftMsg(userId, otherId, log);

        UserSendGiftLog userSendGiftLog = new UserSendGiftLog();
        userSendGiftLog.setFromUserId(userId);
        userSendGiftLog.setToUserId(otherId);
        userSendGiftLog.setContent(log);
        userSendGiftLog.setType("bag");
        userSendGiftLog.setRoomId(roomId);
        userSendGiftLog.setTotalPrice(totalPrice);
        userSendGiftLog.setImg(biggestGift.getImgUrl());
        userSendGiftLogService.save(userSendGiftLog);
    }

    @Override
    public UserPacksack getByUserAndGift(Integer userId, Integer giftId) {
        return getOne(new QueryWrapper<UserPacksack>()
                .eq("user_id", userId)
                .eq("gift_id", giftId));
    }
}
